package com.contory.ssn_lgnd.app.maingame;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Random;

import android.graphics.YuvImage;
import android.hardware.Camera.Size;
import android.util.FloatMath;
import android.util.Log;

import com.contory.ssn_lgnd.app.Assets;
import com.contory.ssn_lgnd.app.comp.DrawPtr;
import com.contory.ssn_lgnd.app.comp.UpdatePtr;
import com.contory.ssn_lgnd.app.comp.ViewObject;
import com.contory.ssn_lgnd.framework.Pool.PoolObjectFactory;
import com.contory.ssn_lgnd.framework.gl.Animation;
import com.contory.ssn_lgnd.framework.gl.SpriteBatcher;
import com.contory.ssn_lgnd.framework.gl.TextureRegion;
import com.contory.ssn_lgnd.framework.math.Circle;
import com.contory.ssn_lgnd.framework.math.OverlapTester;
import com.contory.ssn_lgnd.framework.math.Polygon;
import com.contory.ssn_lgnd.framework.math.Rectangle;
import com.contory.ssn_lgnd.framework.math.Vector2;

public class Enemy implements DrawPtr, UpdatePtr, ColiObjPtr{
	private static final float VIEW_WIDTH = 1f;
	private static final float VIEW_HEIGHT = 0.5f;
	private static final float VELOCITY_SCALA = 2.5f;
	public static final int ID = 2000;
	int groupId = -1;
	
	ViewObject bodyView;
	ViewObject circleView;
	Rectangle rectBound;
	Circle rangeBound;

	float R = 5.0f;
	Vector2 nDir;
	Vector2 des;
	Vector2 incVel;
	Polygon coliBound;
	
	final Fire fire;
	final ColisionManager cm;
	final Player player;
	final EnemyGroup enemyGroup;
	final ParticleEffect ptcEft;
	final TextureEffectGroup tEffectGroup;
	final Random rand;
	
	//ColiInfo coliInfo;
	int energy = 100;
	boolean enableBool = true;

	public static final byte STATE_IDLE = 0;
	byte state = 0;
	
	float coolTime = 0.0f;
	boolean fireEnalbeBool = true;
	static final float COOLTIME_LIMIT = 2.0f;
	
	public Enemy(float strX, float strY, Player player, ColisionManager cm, Fire fire, Random rand, EnemyGroup enemyGroup, ParticleEffect ptcEft, TextureEffectGroup tEffectGroup){
		bodyView = new ViewObject();
		bodyView.setXY_WH_TR(strX, strY, VIEW_WIDTH, VIEW_HEIGHT, Assets.tex_reg_enemy1);
		rectBound = new Rectangle(strX - VIEW_WIDTH / 2, strY - VIEW_HEIGHT / 2, VIEW_WIDTH, VIEW_HEIGHT);
		nDir = new Vector2();
		des = new Vector2();
		incVel = new Vector2();
		
		circleView = new ViewObject();
		circleView.setXY_WH_TR(bodyView.x, bodyView.y, R * 2, R * 2, Assets.tex2_reg_whiteTexel);
		circleView.setRGBA(1, 0, 0, 0.25f);
		coliBound = new Polygon();
		coliBound.lockAddPoint(VIEW_WIDTH, VIEW_HEIGHT);
		coliBound.addPoint(0, 0);
		coliBound.addPoint(1, 0);
		coliBound.addPoint(1, 1);
		coliBound.addPoint(0, 1);
		coliBound.unLockAddPoint();
		coliBound.setPos(strX, strY);
		rangeBound = new Circle(bodyView.x, bodyView.y, R);
		
		this.fire = fire;
		this.player = player;
		this.cm = cm;
		this.enemyGroup = enemyGroup;
		this.rand = rand;
		
		//coliInfo = new ColiInfo();
		//coliInfo.energy = 100;
		//coliInfo.enable = true;
		
		this.tEffectGroup = tEffectGroup;
		this.ptcEft = ptcEft;
		ptcEft.setInit();
		
		energy = 100;
		enableBool = true;
		state = 0;
	}
	
	public void setGroupId(int groupId){
		this.groupId = groupId;
	}
	
	public void setPos(float x, float y){
		bodyView.x = x;
		bodyView.y = y;
	}
	
	@Override
	public void update(float deltaTime) {
		if(!enableBool){	
			ptcEft.setDisable();
			tEffectGroup.addEffect(Assets.ANI_EXPLOSION, Animation.ANIMATION_NONLOOPING, bodyView.x, bodyView.y, 2, 2);
			enemyGroup.removeEnemy(this);
		}
		else{
			updateView(deltaTime);
			rectBound.lowerLeft.set(bodyView.x - VIEW_WIDTH / 2, bodyView.y - VIEW_HEIGHT / 2);
			updateBound();
			updateEft(deltaTime);
			updateFire(deltaTime);
		}
	}
	
	private void updateView(float deltaTime){
		incVel.set(nDir.x * deltaTime * VELOCITY_SCALA, nDir.y * deltaTime * VELOCITY_SCALA);
		setViewDir(nDir.x);
		switch(state){
			case 0:
			break;
			
			case 1: // straight mov
				boolean xExceed = false;
				boolean yExceed = false;
				
				if(nDir.x >= 0){
					if(bodyView.x + incVel.x >= des.x){
						xExceed = true;
						bodyView.x -= (bodyView.x + incVel.x - des.x);
					}
				}
				else{
					if(bodyView.x + incVel.x <= des.x){
						xExceed = true;
						bodyView.x += (des.x - (bodyView.x + incVel.x));
					}
				}
				
				if(nDir.y >= 0){
					if(bodyView.y + incVel.y >= des.y){
						yExceed = true;
						bodyView.y -= (bodyView.y + incVel.y - des.y);
					}
				}
				else{
					if(bodyView.y + incVel.y <= des.y){
						yExceed = true;
						bodyView.y += (des.y - (bodyView.y + incVel.y));
					}
				}

				//Log.d("1", String.valueOf(xExceed + ", " + yExceed));
				bodyView.x += incVel.x;
				bodyView.y += incVel.y;
				if(xExceed && yExceed){
					state = 0;
				}
			break;
		}
	}
	
	public byte getState(){
		return state;
	}
	
	public void setMovToDes(Vector2 des){
		setMovToDes(des.x, des.y);
	}
	
	public void setMovToDes(float x, float y){
		this.des.x = x;
		this.des.y = y;
		nDir.set(des.x - bodyView.x, des.y - bodyView.y);
		nDir.nor();
		state = 1;
	}
	
	private void updateEft(float deltaTime){
		if(!enableBool)
			return;
		if(!(nDir.x == 0 && nDir.y == 0)){
			if(bodyView.w > 0)
				ptcEft.makeParticle(-1, bodyView.x - VIEW_WIDTH / 2, bodyView.y);
			else
				ptcEft.makeParticle(1, bodyView.x + VIEW_WIDTH / 2, bodyView.y);
		}
	}
	
	@Override
	public void draw(SpriteBatcher batcher) {
		if(!enableBool)
			return;
		batcher.drawSprite(bodyView.x, bodyView.y, bodyView.w, bodyView.h, bodyView.tr);
	}
	
	private void updateFire(float deltaTime){
		if(OverlapTester.polygonInCircle(this.rangeBound, player.coliBound)){
			if(fireEnalbeBool){
				fire.fire(new EnemyBullet(this.getPosX(), this.getPosY(), cm, player));
				fireEnalbeBool = false;
			}
		}
		if(!fireEnalbeBool){
			coolTime += deltaTime;
			if(coolTime > COOLTIME_LIMIT){
				fireEnalbeBool = true;
				coolTime = 0.0f;
			}
		}
	}
	
	private void updateBound(){
		coliBound.setPos(bodyView.x, bodyView.y);
		rangeBound.center.set(bodyView.x, bodyView.y);
	}
	
	public void setViewDir(float dirX){
		if(dirX >= 0){
			bodyView.w = VIEW_WIDTH;
		}
		else{
			bodyView.w = -VIEW_WIDTH;
		}
	}
	
	@Override
	public Polygon getColiBound() {
		return coliBound;
	}

	@Override
	public float getPosX() {
		return bodyView.x;
	}

	@Override
	public float getPosY() {
		return bodyView.y;
	}
	
	@Override
	public int getID() {
		return ID;
	}
	
	public int getGroupId(){
		return groupId;
	}

	@Override
	public boolean getEnableBool() {
		return enableBool;
	}

	@Override
	public void setEnable(boolean enableBool) {
		this.enableBool = enableBool;
	}

	@Override
	public void setEnergy(int minusDelta) {
		this.energy += minusDelta;
		if(energy <= 0){
			energy = 0;	
			enableBool = false;
		}
	}

	@Override
	public int getEnergy() {
		return energy;
	}
}
